package com.dragon.logical.service.avttendance.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.logical.service.avttendance.IAttendanceArrangeService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 考勤配置 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-07-31
 */
@Service
public class AttendanceArrangeServiceImpl extends ServiceImpl<AttendanceArrangeMapper, AttendanceArrange> implements IAttendanceArrangeService {

    @Autowired
    AttendanceArrangeMapper arrangeMapper;
    @Autowired
    ArrangePersonnelMapper personnelMapper;
    @Autowired
    ArrangePeriodMapper periodMapper;
    @Autowired
    ArrangePointsMapper pointsMapper;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    AdminDepartmentMapper adminDepartmentMapper;
    @Autowired
    AttendanceMapper attendanceMapper;

    @Override
    public Page<AttendanceArrange> arrangeList(Integer page, Integer limit, String search) {
        Page<AttendanceArrange> arrangePage = new Page<>(page, limit);
        QueryWrapper<AttendanceArrange> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(search), "a.shift_name", search);
        //.or().like(StrUtil.isNotBlank(search),"e.name", search);
        Page<AttendanceArrange> attendanceArrangePage = arrangeMapper.queryByPage(arrangePage, wrapper);
        for (AttendanceArrange arrange : attendanceArrangePage.getRecords()) {
            //获取打卡时间段
            List<ArrangePeriod> arrangePeriods = periodMapper.selectList(new QueryWrapper<ArrangePeriod>()
                    .lambda().eq(ArrangePeriod::getArrangeId, arrange.getId()));
            for (ArrangePeriod period : arrangePeriods) {
                if (StrUtil.isNotBlank(period.getPointsId())) {
                    List<Integer> pid = Stream.of(period.getPointsId().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                    List<ArrangePoints> arrangePoints = pointsMapper.selectBatchIds(pid);
                    period.setPointsList(arrangePoints);
                    ArrayList<String> strings = new ArrayList<>();
                    for (Integer integer : pid) {
                        List<ArrangePoints> pointsList = pointsMapper.selectList(new QueryWrapper<ArrangePoints>()
                                .lambda().eq(ArrangePoints::getId, integer));
                        for (ArrangePoints points : pointsList) {
                            strings.add(points.getPointsName());
                        }
                        period.setPointsName(strings);
                    }
                }
            }
            arrange.setPeriodList(arrangePeriods);
            //获取人员配置
            String adminNames = personnelMapper.getAdminNames(arrange.getId());
            arrange.setAdminNames(adminNames);
        }
        return attendanceArrangePage;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Integer arrangeAdd(AttendanceArrange arrange) {
        // 添加主表信息
        arrange.setCreateTime(DateUtil.date());
        arrangeMapper.insert(arrange);
        // 添加子表信息
        if(arrange.getAdminIds()!=null){
            List<ArrangePersonnel> arrangePersonnels = personnelMapper.selectList(
                    new LambdaQueryWrapper<ArrangePersonnel>().in(ArrangePersonnel::getAdminId,arrange.getAdminIds())
            );
            if(arrangePersonnels.size()!=0){
                throw new CustomException(ResultCode.ATTENDANCE_ADMIN_IS_EXIT);
            }
            //添加人员子表数据
            arrange.getAdminIds().forEach(adminId -> {
                ArrangePersonnel arrangePersonnel = new ArrangePersonnel();
                arrangePersonnel.setArrangeId(arrange.getId());
                arrangePersonnel.setAdminId(adminId);
                personnelMapper.insert(arrangePersonnel);
            });
        }
        // 添加
        if (arrange.getPeriodList() != null) {
            for (ArrangePeriod period : arrange.getPeriodList()) {
                period.setArrangeId(arrange.getId());
                periodMapper.insert(period);
            }
        }
        return arrange.getId();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateArrange(AttendanceArrange arrange) {
        AttendanceArrange attendanceArrange = arrangeMapper.selectById(arrange.getId());
        if (attendanceArrange == null) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        // 修改子表信息
        if(arrange.getAdminIds()!=null){
            List<ArrangePersonnel> arrangePersonnels = personnelMapper.selectList(
                    new LambdaQueryWrapper<ArrangePersonnel>()
                            .ne(ArrangePersonnel::getArrangeId,arrange.getId())
                            .in(ArrangePersonnel::getAdminId,arrange.getAdminIds())
            );
            if(arrangePersonnels.size()!=0){
                throw new CustomException(ResultCode.ATTENDANCE_ADMIN_IS_EXIT);
            }
            // 删除所有子表信息数据
            personnelMapper.delete(new LambdaQueryWrapper<ArrangePersonnel>().eq(ArrangePersonnel::getArrangeId,arrange.getId()));
            //添加人员子表数据
            arrange.getAdminIds().forEach(adminId -> {
                ArrangePersonnel arrangePersonnel = new ArrangePersonnel();
                arrangePersonnel.setArrangeId(arrange.getId());
                arrangePersonnel.setAdminId(adminId);
                personnelMapper.insert(arrangePersonnel);
            });
        }
        if (arrange.getPeriodList() != null) {
            periodMapper.delete(new QueryWrapper<ArrangePeriod>().lambda()
                    .eq(ArrangePeriod::getArrangeId, attendanceArrange.getId()));
            for (ArrangePeriod period : arrange.getPeriodList()) {
                period.setArrangeId(arrange.getId());
                periodMapper.insert(period);
            }
        }
        arrangeMapper.updateById(arrange);
    }

    @Override
    public AttendanceArrange seeDetails(Integer id) {
        AttendanceArrange arrange = arrangeMapper.selectById(id);
        /*获取人员配置*/
        QueryWrapper<ArrangePersonnel> wrapper = new QueryWrapper<>();
        List<ArrangePersonnel> personnelList = personnelMapper.selectList(wrapper.lambda()
                .eq(ArrangePersonnel::getArrangeId, id));
        List<Integer> adminIdList = personnelList.stream().map(ArrangePersonnel::getAdminId).collect(Collectors.toList());
        arrange.setAdminIds(adminIdList);
        //用户名字
        ArrayList<String> nameList = new ArrayList<>();
        personnelList.forEach(per -> {
            String username = adminMapper.selectUsernameById(per.getAdminId());
            nameList.add(username);
        });
        arrange.setAdminNames(nameList.stream().collect(Collectors.joining(",")));
        //获取用户部门
        List<AdminDepartment> list = new ArrayList<>();
        adminIdList.forEach(adminId -> {
            QueryWrapper<AdminDepartment> adWrapper = new QueryWrapper<>();
            AdminDepartment adminDepartment = adminDepartmentMapper.selectOne(adWrapper.lambda()
                    .eq(AdminDepartment::getAdminId, adminId));
            list.add(adminDepartment);
        });
        arrange.setAdList(list);
        /*获取时段配置*/
        List<ArrangePeriod> periodList = periodMapper.selectList(new QueryWrapper<ArrangePeriod>()
                .lambda().eq(ArrangePeriod::getArrangeId, id));
        for (ArrangePeriod period : periodList) {
            if (StrUtil.isNotBlank(period.getPointsId())) {
                List<Integer> pid = Stream.of(period.getPointsId().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                List<ArrangePoints> arrangePoints = pointsMapper.selectBatchIds(pid);
                period.setPointsList(arrangePoints);
                ArrayList<String> strings = new ArrayList<>();
                for (Integer integer : pid) {
                    List<ArrangePoints> pointsList = pointsMapper.selectList(new QueryWrapper<ArrangePoints>()
                            .lambda().eq(ArrangePoints::getId, integer));
                    for (ArrangePoints points : pointsList) {
                        strings.add(points.getPointsName());
                    }
                    period.setPointsName(strings);
                }
            }
        }
        arrange.setPeriodList(periodList);
        return arrange;
    }

//    @Override
//    public AttendanceArrange seeDetailsByAdminId(Integer adminId) {
//        List<ArrangePersonnel> personnelList = personnelMapper.selectList(null);
//        for (ArrangePersonnel personnel : personnelList) {
//            List<String> list = Arrays.asList(personnel.getAdminId().split(","));
//            if (list.contains(String.valueOf(adminId))==true){
//                List<ArrangePeriod> period = periodMapper.selectList(new QueryWrapper<ArrangePeriod>().lambda()
//                        .eq(ArrangePeriod::getArrangeId, personnel.getArrangeId()));
//                for (ArrangePeriod arrangePeriod : period) {
//                    if (StrUtil.isNotBlank(arrangePeriod.getPointsId())){
//                        List<String> pointsId = Arrays.asList(arrangePeriod.getPointsId().split(","));
//                        List<Integer> ids = pointsId.stream().map(Integer::valueOf).collect(Collectors.toList());
//
//                        ArrayList<String> strings = new ArrayList<>();
//                        for (Integer integer : ids) {
//                            List<ArrangePoints> pointsList = pointsMapper.selectList(new QueryWrapper<ArrangePoints>()
//                                    .lambda().eq(ArrangePoints::getId, integer));
//                            for (ArrangePoints points : pointsList) {
//                                strings.add(points.getPointsName());
//                            }
//                            arrangePeriod.setPointsName(strings);
//                        }
//                        List<ArrangePoints> arrangePoints = pointsMapper.selectBatchIds(ids);
//                        arrangePeriod.setPointsList(arrangePoints);
//
//                    }
//
//                }
//                AttendanceArrange arrange = arrangeMapper.selectById(personnel.getArrangeId());
//                if (arrange != null){
//                    arrange.setPeriodList(period);
//                    return arrange;
//                }
//            }
//
//        }
//        return new AttendanceArrange();
//    }

    @Override
    public AttendanceArrange seeDetailsByAdminId(Integer adminId,Integer arrangeId) {
        Admin admin = adminMapper.selectById(adminId);
        Integer arrangeIds = 0;
        if(arrangeId==null){
            ArrangePersonnel arrangePersonnel = personnelMapper.selectOne(
                    new LambdaQueryWrapper<ArrangePersonnel>().eq(ArrangePersonnel::getAdminId,adminId)
            );
            if(arrangePersonnel == null){
                if (admin.getAccountType() != 1){
                    throw new CustomException(ResultCode.ATTENDANCE_CONFIG_IS_NOT_FOUND);
                }
                return null;
            }
            arrangeIds = arrangePersonnel.getArrangeId();
        } else {
            arrangeIds = arrangeId;
        }
        List<ArrangePeriod> period = periodMapper.selectList(new QueryWrapper<ArrangePeriod>().lambda()
                .eq(ArrangePeriod::getArrangeId, arrangeIds));
        for (ArrangePeriod arrangePeriod : period) {
            if (StrUtil.isNotBlank(arrangePeriod.getPointsId())) {
                List<String> pointsId = Arrays.asList(arrangePeriod.getPointsId().split(","));
                List<Integer> ids = pointsId.stream().map(Integer::valueOf).collect(Collectors.toList());
                ArrayList<String> strings = new ArrayList<>();
                for (Integer integer : ids) {
                    List<ArrangePoints> pointsList = pointsMapper.selectList(new QueryWrapper<ArrangePoints>()
                            .lambda().eq(ArrangePoints::getId, integer));
                    for (ArrangePoints points : pointsList) {
                        strings.add(points.getPointsName());
                    }
                    arrangePeriod.setPointsName(strings);
                }
                List<ArrangePoints> arrangePoints = pointsMapper.selectBatchIds(ids);
                arrangePeriod.setPointsList(arrangePoints);
            }

        }
        AttendanceArrange arrange = arrangeMapper.selectById(arrangeIds);
        if (arrange != null) {
            arrange.setPeriodList(period);
            return arrange;
        }
        return new AttendanceArrange();
    }

    @Override
    public void arrangeDelete(Integer id) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String time = sdf.format(new Date());
        QueryWrapper<Attendance> wrapper = new QueryWrapper<>();
        List<Attendance> attendances = attendanceMapper.selectList(wrapper.lambda().eq(Attendance::getArrangeId, id).eq(Attendance::getCreateTime, time));
        if( attendances.size() != 0 ) {
            throw new CustomException(ResultCode.IS_EXIST);
        }

        //先删除 时段关联表的数据
        List<ArrangePeriod> periodList = periodMapper.selectList(new QueryWrapper<ArrangePeriod>()
                .lambda().eq(ArrangePeriod::getArrangeId, id));
        if (periodList != null) {
            for (ArrangePeriod period : periodList) {
                //删除 考勤点 数据
                periodMapper.deleteById(period);
            }
        }

        //删除 人员 数据
        List<ArrangePersonnel> personnel = personnelMapper.selectList(new QueryWrapper<ArrangePersonnel>()
                .lambda().eq(ArrangePersonnel::getArrangeId, id));
        if (personnel != null || personnel.size() != 0) {
            for (ArrangePersonnel arrangePersonnel : personnel) {
                personnelMapper.deleteById(arrangePersonnel);
            }
        }
        arrangeMapper.deleteById(id);
    }


}
